/*
 * Copyright 2007 Jeffrey Palm
 */

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.List;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

import org.farng.mp3.*;
import org.farng.mp3.id3.*;

final class Pitchfork extends AbstractFinder {

  public String name() {return "Pitchfork";}
  private final static String main = "http://pitchforkmedia.com";

  protected void findRest(ITunes itunes, Progress p) throws Exception {
    //
    // we'll probably resuse this
    //
    String line;
    BufferedReader in;
    //
    // Find the pages
    //
    in = reader(main);
    Set hrefs = new HashSet();
    while ((line = in.readLine()) != null) {
      line = line.trim();
      if (line.startsWith("<a href=\"/page/forkcast/")) {
        int iquote1 = line.indexOf("\"");
        if (iquote1 == -1) continue;
        int iquote2 = line.indexOf("#",iquote1+1);
        if (iquote2 == -1) continue;
        String href = line.substring(iquote1+1,iquote2);
        note("found href: "+href);
        hrefs.add(href);     
      }
    }
    in.close();
    Collection items = new HashSet();
    String adURL = null;
    String adImg = null;
    for (Iterator it = hrefs.iterator(); it.hasNext();) {
      String href = (String)it.next();
      String link = main + href;
      in = reader(link);
      note("have link: " + link);
      while ((line = in.readLine()) != null) {
        line = line.trim();
        //
        // try to get an ad
        //
        // <a href="http://ahs.pitchforkmedia.com/oasisc.php?s=2047&w=728&h=90&t=_blank">
        if (line.startsWith("<a href=\"http://ahs.pitchforkmedia")) {
          int iq1 = line.indexOf("\"");
          if (iq1 != -1) {
            int iq2 = line.indexOf("\"",iq1);
            if (iq2 != -1 && iq2 > iq1) {
              adURL = line.substring(iq1+1,iq2);
              continue;
            }
          }
        }
        // <img src="http://ahs.pitchforkmedia.com/oasisi.php?s=2047&w=728&h=90&t=_blank" width="728" height="90" border="0">
        if (line.startsWith("<img src=\"http://ahs.pitchforkmedia")) {
          int iq1 = line.indexOf("\"");
          if (iq1 != -1) {
            int iq2 = line.indexOf("\"",iq1);
            if (iq2 != -1 && iq2 > iq1) {
              adImg = line.substring(iq1+1,iq2);
              continue;
            }
          }
        }
        //
        // try to get the items
        //
        String target = "<a href=";
        int ihref = line.indexOf(target);
        if (ihref == -1) continue;
        char c = line.charAt(ihref+target.length());
        int iquote1 = line.indexOf(c,ihref+1);
        if (iquote1 == -1) continue;
        int iquote2 = line.indexOf(c,iquote1+1);
        if (iquote2 == -1) continue;
        String l = line.substring(iquote1+1,iquote2);
        String name = null;
        int igt = line.indexOf(">",iquote2);
        if (igt != -1) {
          int ilt = line.indexOf("<",igt);
          if (ilt != -1) name = line.substring(igt+1,ilt);
        }
        if (Util.isEmpty(name)) name = getName(l);
        if (isAudio(l) || isVideo(l)) {
          note("adding " + name + ":" + l);
          items.add(new TableItem(name,l));
        }
      }
      in.close();
    }
    note("items:"+items);
    String html;
    if (adURL != null && adImg != null) {
      html  = "<html><body><center>";
      html += "<a href=\"" + adURL + "\"><img src=\"" + adImg + "\" /></a>";
      html += "<br/>";
      html += "<b>Downloading....</b>";
      html += "</center></body></html>";
    } else {
      html = null;
    }
    DownloadFrame df = new DownloadFrame(html,items,p);
    df.pack();
    CenterHelper.center(df);
    df.setVisible(true);
  }

  /**
   * Replace the &quot; with "s
   */
  private static String replaceQuotes(String s) {
    return ReplaceSubstring.oldReplace(s,"&quot;","\"");
  }

  private class DownloadFrame extends JFrame {
    
    DownloadFrame(final String html, final Collection items, final Progress p) {
      getContentPane().setLayout(new BorderLayout());
      JPanel top = new JPanel();
      DefaultListModel mod = new DefaultListModel();
      final JList t = new JList(mod);
      top.setLayout(new BoxLayout(top,BoxLayout.X_AXIS));
      
      top.add(new JButton(new AbstractAction("Download") {
          public void actionPerformed(ActionEvent e) {
              new Thread(new Runnable() {
                  public void run() {
                    try {
                      HTMLFrame hf = null;
                      if (html != null) {
                        hf = new HTMLFrame(html);
                        hf.pack();
                        CenterHelper.center(hf);
                        hf.setVisible(true);
                      }
                      List selected = new ArrayList();
                      Object[] sels = t.getSelectedValues();
                      int[] sel = t.getSelectedIndices();
                      for (int i=0; i<sels.length; i++) {
                        selected.add(sels[i]);
                      }
                      download(selected,p,t,sel);
                      setVisible(false);
                      dispose();
                      if (hf != null) {
                        hf.setVisible(false);
                        hf.dispose();
                      }
                    } catch (Exception ee) {ee.printStackTrace();}
                  }}).start();
          }
        }));
      top.add(new JButton(new AbstractAction("Quit") {
          public void actionPerformed(ActionEvent e) {
            System.exit(0);
          }
        }));
      getContentPane().add(top,BorderLayout.NORTH);
      for (Iterator it = items.iterator(); it.hasNext();) {
        mod.addElement(it.next());
      }
      getContentPane().add(new JScrollPane(t),BorderLayout.CENTER);
      int[] all = new int[items.size()];
      for (int i=0; i<all.length; i++) all[i] = i;
      t.setSelectedIndices(all);

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      getContentPane().setPreferredSize(new Dimension(600,400));
    }
  }

  private void download(Collection items, Progress p, JList lst, int[] sel) throws Exception {
    p.reset();
    p.setMax(items.size());
    //
    // First delete all the old files
    //
    File outDirMovies = Util.newDir(Util.newDir(System.getProperty("user.home")),"Movies");
    File outDirMusic = Util.newDir(Util.getItunesDir(), new String[]{"iTunes Music","Pitchfork","Unknown Album"});
    File[] fs = outDirMusic.listFiles();
    if (fs != null) {
      for (int i=0; i<fs.length; i++) fs[i].delete();
    }
    note("downloading to " + outDirMusic.getAbsolutePath());
    //
    // Download them all
    //
    lst.setSelectedIndex(sel[0]);
    boolean firstTime = true;
    int count = 0;
    for (Iterator it = items.iterator(); it.hasNext();) {
      TableItem item = (TableItem)it.next();
      File outDir = isAudio(item.link) ? outDirMusic : outDirMovies;
      String name = getName(item.name);
      lst.setSelectedIndex(sel[count]);
      firstTime = false;
      p.update("Downloading " + name + "...",1);
      if (isCancelled()) break;
      download(item,outDir);
      count++;
    }
    //
    // Create a playlist
    //
    JOptionPane.showMessageDialog(null,count + " file(s) written to " + outDirMusic + " and " + outDirMovies);
  }

  private String fileName(String s) {
    int ilastSlash = s.lastIndexOf("/");
    return ilastSlash == -1 ? s : s.substring(ilastSlash+1);
  }

  private void download(TableItem item, File outDir) throws Exception {
    String link = item.link;
    String fileName = getName(fileName(link));
    File outFile = new File(outDir,fileName);
    Util.wget(link,outFile);
  }

  private static String getName(String n) {
    int ilastSlash = n.lastIndexOf("/");
    if (ilastSlash == -1) return n;
    int ilastDot = n.lastIndexOf(".");
    if (ilastDot == -1 || ilastDot<ilastSlash) return n;
    String r = n.substring(ilastSlash+1,ilastDot);
    return ReplaceSubstring.oldReplace(r,"%20"," ");
  }

  private static class TableItem {
    final String name;
    final String link;
    TableItem(String name, String link) {
      this.name = replaceQuotes(name);
      this.link = link;
    }
    public String toString() {
      String s = name + " (";
      s += isAudio(link) ? "audio" : "video";
      s += ")";
      return s;
    }
    public int hashCode() {return link.hashCode();}
    public boolean equals(Object o) {
      if (!(o instanceof TableItem)) return false;
      TableItem that = (TableItem)o;
      return that.link.equals(this.link);
    }
  }

  private static boolean isAudio(String link) {
    String[] exts = {
      "mp3",
      "m4p",
    };
    return isSomething(link,exts);
  }

  private static boolean isVideo(String link) {
    String[] exts = {
      "mp4",
      "mov",
      "m4v",
      "mpg",
      "mpeg",
    };
    return isSomething(link,exts);
  }

  private static boolean isSomething(String link,String[] exts) {
    for (int i=0; i<exts.length; i++) {
      if (link.endsWith(exts[i])) return true;
    }
    return false;
  }

  public static void main(String[] args) throws Exception {
    new Pitchfork().find(new ITunes(),Progress.DEFAULT);
  }

}